﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Forms;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Xml;
using Application = System.Windows.Application;
using MessageBox = System.Windows.MessageBox;

namespace CSVFormater
{
    /// <summary>
    /// Converter.xaml 的交互逻辑
    /// </summary>
    public partial class Converter : Window
    {
        private DataSet _tempCsvDataSet;
        private List<String> _categoryOneList;
        private List<String> _categoryTwoList;
        private List<String> _categoryTwoModelList;
        private List<String> _categoryThreeList;
        private List<String> _categoryFourList;
        private Formater formater;
        

        public Converter(DataSet csvFileData)
        {
            InitializeComponent();
           
            _tempCsvDataSet = csvFileData;

            dataGrid_preView.DataSource = _tempCsvDataSet;
            this.dataGrid_preView.DataMember = "csv";

            // load table
            LoadTables();

            // load config
            _categoryOneList = new List<string>();
            _categoryTwoList = new List<string>();
            _categoryThreeList = new List<string>();
            _categoryTwoModelList = new List<string>();
            _categoryFourList = new List<string>();
            
            LoadConfig();
        }

        #region load Configure
        private void LoadConfig()
        {
            ReadSetting();
        }
        public void ReadSetting()
        {
            // load config document for current assembly
            XmlDocument doc = LoadConfigDocument();

            #region categoryOne
            // retrieve category node
            XmlNode node = doc.SelectSingleNode("//categoryOne");
            if (node == null)
                throw new InvalidOperationException("appSettings section not found in config file.");
            try
            {
                // select the 'add' element that contains the key
                XmlNodeList elems = node.SelectNodes("//categoryOne//category");
                if (elems != null)
                    foreach (XmlElement elem in elems)
                    {
                        var tempItem = new ComboBoxItem();
                       
                        string header = elem.GetAttribute("name");
                        string code = elem.GetAttribute("code");

                        tempItem.Content = String.Format(header);
                        Category1.Items.Add(tempItem);
                        _categoryOneList.Add(code);
                    }
            }
            catch (Exception)
            {

                throw;
            }
            #endregion
            #region categoryTwo
            // retrieve category node
            node = doc.SelectSingleNode("//categoryTwo");
            if (node == null)
                throw new InvalidOperationException("appSettings section not found in config file.");
            try
            {
                // select the 'add' element that contains the key
                var elems = node.SelectNodes("//categoryTwo//category");
                if (elems != null)
                    foreach (XmlElement elem in elems)
                    {
                        var tempItem = new ComboBoxItem();

                        string header = elem.GetAttribute("name");
                        string code = elem.GetAttribute("code");
                        string model = elem.GetAttribute("model");

                        tempItem.Content = String.Format(header);
                        Category2.Items.Add(tempItem);
                        _categoryTwoList.Add(code);
                        _categoryTwoModelList.Add(model);
                    }
            }
            catch (Exception)
            {

                throw;
            }
            #endregion
            #region categoryThree
            // retrieve category node
            node = doc.SelectSingleNode("//categoryThree");
            if (node == null)
                throw new InvalidOperationException("appSettings section not found in config file.");
            try
            {
                // select the 'add' element that contains the key
                var elems = node.SelectNodes("//categoryThree//category");
                if (elems != null)
                    foreach (XmlElement elem in elems)
                    {
                        var tempItem = new ComboBoxItem();

                        string header = elem.GetAttribute("name");
                        string code = elem.GetAttribute("code");

                        tempItem.Content = String.Format(header);
                        Category3.Items.Add(tempItem);
                        _categoryThreeList.Add(code);
                    }
            }
            catch (Exception)
            {

                throw;
            }
            #endregion
            #region categoryFour
            // retrieve category node
            node = doc.SelectSingleNode("//categoryFour");
            if (node == null)
                throw new InvalidOperationException("appSettings section not found in config file.");
            try
            {
                // select the 'add' element that contains the key
                var elems = node.SelectNodes("//categoryFour//category");
                if (elems != null)
                    foreach (XmlElement elem in elems)
                    {
                        var tempItem = new ComboBoxItem();

                        string header = elem.GetAttribute("name");
                        string code = elem.GetAttribute("code");

                        tempItem.Content = String.Format(header);
                        Category4.Items.Add(tempItem);
                        _categoryFourList.Add(code);
                    }
            }
            catch (Exception)
            {

                throw;
            }
            #endregion

        }
        private static XmlDocument LoadConfigDocument()
        {
            XmlDocument doc = null;
            try
            {
                doc = new XmlDocument();
                doc.Load(GetConfigFilePath());
                return doc;
            }
            catch (System.IO.FileNotFoundException e)
            {
                throw new Exception("No configuration file found.", e);
            }
        }

        private static string GetConfigFilePath()
        {
            return "config\\category.config";
        }
        #endregion

  
        #region load table
        private void LoadTables()
        {
            /*
            // Conncets to database, and selects the table names.
            SqlConnection cn = new SqlConnection(prop.sqlConnString);
            SqlDataAdapter da = new SqlDataAdapter("select name from dbo.sysobjects where xtype = 'U' and name <> 'dtproperties' order by name", cn);
           
            */

            // Fills the list to an DataTable.
            
            for(int sizeOfTable= 0; sizeOfTable < _tempCsvDataSet.Tables.Count ; sizeOfTable++)
            {
                var dt = _tempCsvDataSet.Tables[sizeOfTable];

                // Clears the ListBox
                this.lbxTables.Items.Clear();

                // Fills the table names to the ListBox.
                // Notifies user if there is no user table in the database yet.
                if (dt.Rows.Count == 0)
                {
                    MessageBox.Show(
                        String.Format("There is no user table in the specified database. Import a CSV file first."));
                    this.lbxTables.Items.Add("< no user table in database >");
                    this.btnExportToCSV.IsHitTestVisible = false;
                }
                else
                {
                    this.btnExportToCSV.IsHitTestVisible = true;
                    this.lbxTables.Items.Add(dt.TableName);
                }
            }
            this.lbxTables.SelectedIndex = 0;
        }


        #endregion
        /*
         * Returns the specified separator character
         */

        private string separator
        {
            get
            {
                if ((bool) rdbSemicolon.IsChecked)
                {
                    return ";";
                }
                else if ((bool) rdbTab.IsChecked)
                {
                    return "\t";
                }
                else if ((bool) rdbSeparatorOther.IsChecked )
                {
                    if (txtSeparatorOtherChar.Text.Length == 1)
                    {
                        return txtSeparatorOtherChar.Text;
                    }
                    else
                    {
                        MessageBox.Show("Invalid separator character.");
                        rdbSemicolon.IsChecked = true;
                        return ";";
                    }
                }
                else
                {
                    return ";";
                }
            }
        }



        private void TxtSeparatorOtherCharTextChanged(object sender, EventArgs e)
        {
            this.rdbSeparatorOther.IsChecked = true;
        }


        /*
         * Returnes the appropriate Encoding object.
         */

        private Encoding EncodingCsv
        {
            get
            {
                if ((bool) rdbUnicode.IsChecked)
                {
                    return Encoding.Unicode;
                }
                if ((bool)radCnSimple.IsChecked)
                {
                    return Encoding.GetEncoding("gb2312");
                }
             
                if ((bool) rdbUTF7.IsChecked)
                {
                    return Encoding.UTF7;
                }
                if ((bool) rdbUTF8.IsChecked)
                {
                    return Encoding.UTF8;
                }
                return Encoding.Unicode;

                // You can add other options, for ex.:
                //return Encoding.GetEncoding("iso-8859-2");
                //return Encoding.Default;
            }
        }





        /*
         * Exports data to the CSV file.
         */

        private void exportToCSVfile(string fileOut)
        {

            /*
            // Connects to the database, and makes the select command.
            SqlConnection conn = new SqlConnection(prop.sqlConnString);
            string sqlQuery = "select * from " + this.lbxTables.SelectedItem.ToString();
            SqlCommand command = new SqlCommand(sqlQuery, conn);
            conn.Open();

            // Creates a SqlDataReader instance to read data from the table.
            SqlDataReader dr = command.ExecuteReader();
            */

            // Retrives the schema of the table.

            
            DataTable dataTable = _tempCsvDataSet.Tables[0];

            // Creates the CSV file as a stream, using the given encoding.
            StreamWriter sw = new StreamWriter(fileOut, false, this.EncodingCsv);

            string strRow; // represents a full row

            // Writes the column headers if the user previously asked that.
            if ((bool) chkFirstRowColumnNames.IsChecked)
            {
                sw.WriteLine(columnNames(dataTable, this.separator));
            }

            // Reads the rows one by one from the SqlDataReader
            // transfers them to a string with the given separator character and
            // writes it to the file.
            for (int rowIndex = 0; rowIndex < dataTable.Rows.Count; rowIndex++)
            {
                strRow = "";
                for (int i = 0; i < dataTable.Columns.Count; i++)
                {
                    strRow += dataTable.Rows[rowIndex][i].ToString();
                    if (i < dataTable.Columns.Count - 1)
                    {
                        strRow += this.separator;
                    }
                }
                sw.WriteLine(strRow);

            }

            // Closes the text stream and the database connenction.
            sw.Close();

            // Notifies the user.
            MessageBox.Show("已经成功导出文件");
        }


        /*
         * Retrieves the header row from the schema table.
         */

        private string columnNames(DataTable dtSchemaTable, string delimiter)
        {
            string strOut = "";
            if (delimiter.ToLower() == "tab")
            {
                delimiter = "\t";
            }

            for (int i = 0; i < dtSchemaTable.Columns.Count; i++)
            {
                strOut += dtSchemaTable.Columns[i].ColumnName;
                if (i < dtSchemaTable.Columns.Count - 1)
                {
                    strOut += delimiter;
                }

            }
            return strOut;
        }
     


        private void ExportButtonClick(object sender, RoutedEventArgs e)
        {
            _tempCsvDataSet = formater.Format(_tempCsvDataSet);
            formater.RenameAllPhotos(ref _tempCsvDataSet);
            
            ExportToCsv();
            
        }



        /*
         * Asks a filename and location from the user to export the data, and
         * runs the export operation.
         */
        private void ExportToCsv()
        {

            //Asks the filenam with a SaveFileDialog control.

            var saveFileDialogCSV = new SaveFileDialog();
            saveFileDialogCSV.InitialDirectory = Environment.CurrentDirectory;

            saveFileDialogCSV.Filter = "CSV files (*.csv)|*.csv|All files (*.*)|*.*";
            saveFileDialogCSV.FilterIndex = 1;
            saveFileDialogCSV.RestoreDirectory = true;

            if (saveFileDialogCSV.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                // Runs the export operation if the given filenam is valid.
                exportToCSVfile(saveFileDialogCSV.FileName);
            }
        }

        /* Refresh the list of user tables.
      */

        private void btnRefresh_Click(object sender, EventArgs e)
        {
            if(checkReady())
            {
                LoadTables();
            }           
        }

        private void preview_Click(object sender, RoutedEventArgs e)
        {
            if (checkReady())
            {
                if (Category3.SelectedIndex != -1 && Category4.SelectedIndex != -1)
                {
                    formater = new Formater(
                    _categoryOneList[Category1.SelectedIndex],
                    _categoryTwoList[Category2.SelectedIndex],
                    _categoryTwoModelList[Category2.SelectedIndex],
                    _categoryThreeList[Category3.SelectedIndex],
                    _categoryFourList[Category4.SelectedIndex],
                    fromFolderOpenFolderDialog.Path,
                    toFolderOpenFolderDialog.Path);
                }
                else
                {
                    formater = new Formater(
                    _categoryOneList[Category1.SelectedIndex],
                    _categoryTwoList[Category2.SelectedIndex],
                    _categoryTwoModelList[Category2.SelectedIndex],
                    fromFolderOpenFolderDialog.Path,
                    toFolderOpenFolderDialog.Path);
                }

                
                dataGrid_preView.DataSource = formater.Format(_tempCsvDataSet);
                // this.dataGrid_preView.DataMember = "csv";

                btnExportToCSV.IsEnabled = true;
            }    
        }
        Boolean checkReady()
        {
            if(Category1.SelectedIndex == -1)
            {
                InfoStatusBarItem.Text = "请选择类别一";
                return false;

            }
            if(Category2.SelectedIndex==-1)
            {
                InfoStatusBarItem.Text = "请选择类别二";
                return false;
            }
            if(!(fromFolderOpenFolderDialog.Path.Length > 0))
            {
                InfoStatusBarItem.Text = "请选择：被导出文件夹";
                return false;
            }
            if(!(toFolderOpenFolderDialog.Path.Length > 0))
            {
                InfoStatusBarItem.Text = "请选择：目标文件夹";
                return false;
            }
            return true;
        }
        
    }
}
